package com.lzk.ws;

import com.alibaba.fastjson.JSONObject;
import com.lzk.controller.front.RoomController;
import com.lzk.controller.front.UserController;
import com.lzk.model.Player;
import com.lzk.model.Room;
import com.lzk.model.ZcData;
import com.lzk.model.ZcUser;
import com.lzk.service.impl.RoomServiceImpl;

import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.util.*;

@ServerEndpoint("/gameWs/{token}")
public class GameWebSocket {
    Session session;
    String token;
    ZcUser user;
    static Map<String, GameWebSocket> map = new HashMap<String, GameWebSocket>();

    @OnOpen
    public void onOpen(Session session, @PathParam("token") String token) {
        this.session = session;
        this.token = token;
        user = UserController.tokenMap.get(token);
        if (user == null) {
            //提示未找到
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("method", "error");
            jsonObject.put("msg", "未登录！");
            session.getAsyncRemote().sendText(jsonObject.toString());
            return;
        }
        map.put(token, this);
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("method", "otherEnterRoom");
        jsonObject.put("userName", user.getUserName());
        sendMsg(token, jsonObject.toString());
        System.out.println(user.getUserName() + "进入房间");
    }

    @OnClose
    public void onClose() {
        if (map.get(token) == null) return;
        Room thisRoom = RoomController.playerRoom.get(user.getId());
        if(thisRoom==null){//不在房间内，证明是通过按钮退出的，直接return
            return;
        }
        outRoom();
        map.remove(token);
        System.out.println(user.getUserName() + "退出房间！");
    }

    private void outRoom() {
        //1.判断账户情况
        if (token == null) return;
        ZcUser user = UserController.tokenMap.get(token);
        if (user == null) return;
        Player player = RoomController.playerMap.get(user.getId());
        //2.房间情况（当前用户是否在房间内，房间是否存在）
        //获取当前房间对象
        if (RoomController.playerRoom.get(user.getId()) == null) {
            return;
        }
        Room thisRoom = RoomController.playerRoom.get(user.getId());
        if (!RoomController.rooms.contains(thisRoom)) {
            return;
        }
        //3.用户退出房间是否会影响游戏进行
        //判断角色
        if (player.getRole() == RoomServiceImpl.blackRole.getValueId() || player.getRole() == RoomServiceImpl.whiteRole.getValueId()) {
            //退出之前把游戏关掉
            //发送游戏关闭ws
            //角色关闭
            ZcData normalStatus = ZcData.dao.findFirst("SELECT * FROM `zc_data` WHERE `key` = ? AND `value` = ?", "roomStatus", "等待中");
            if (normalStatus == null) return;
            thisRoom.setRoomStatus(normalStatus.getValueId());//游戏结束
            for (Player p:thisRoom.getPlayers()){
                p.setPlayerStatus(RoomServiceImpl.wzbData.getValueId());
            }
            //让房间里的所有人关闭窗体
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("method","otherOutRoomOverGame");
            GameWebSocket.sendMsg(token,jsonObject.toString());

            int thisRole = player.getRole();
            //继承给房间里的其他人
            for (Player p : thisRoom.getPlayers()) {
                if (p.getRole() != RoomServiceImpl.blackRole.getValueId() && p.getRole() != RoomServiceImpl.whiteRole.getValueId()) {
                    p.setRole(thisRole);//角色继承给其他人
                    break;
                }
            }
        }

        JSONObject jsonObject = new JSONObject();
        jsonObject.put("method", "otherOutRoom");
        jsonObject.put("userName", user.getUserName());
        sendMsg(token, jsonObject.toString());

        //4.如果用户退出房间，房间内每人，销毁房间(写这个方法的时候注意地址和值)
        RoomController.playerRoom.remove(player.getId());
        //thisRoom.getPlayers().remove(player);//必须重写Player的equals
        for (Player p : thisRoom.getPlayers()) {
            if (p.getId() == player.getId()) {
                thisRoom.getPlayers().remove(p);
                break;
            }
        }
        RoomController.playerMap.remove(player.getId());
        //发生变化刷新表格
        JSONObject msg = new JSONObject();
        msg.put("method", "freshTable");
        HallWebSocket.sendMsg(token, msg.toString());
        if (thisRoom.getPlayers().size() == 0) {
            RoomController.rooms.remove(thisRoom);
            return;
        }
        //5.如果用户是房主退出房间，随机一人成为房主
        if (thisRoom.getRoomOwner().equals(player)) {
            //当退出玩家是房主
            Random random = new Random();
            Player p = thisRoom.getPlayers().get(random.nextInt(thisRoom.getPlayers().size()));
            thisRoom.setRoomOwner(p);//新房主
        }
    }

    @OnMessage
    public void onMessage(String msg) {
        JSONObject obj = JSONObject.parseObject(msg);
        String method = (String) obj.get("method");
        if ("sendChat".equals(method)) {
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("method", method);
            jsonObject.put("msg", obj.get("msg"));
            jsonObject.put("userName", user.getUserName());
            sendMsg(token, jsonObject.toString());
        }else if ("down".equals(method)){
            sendMsg(token,msg);
        }
    }

    /**
     * 发送信息给房间里的所有人（除了自己）
     * @param token
     * @param msg
     */
    public static void sendMsg(String token, String msg) {
        Set<String> keys = map.keySet();
        Room thisRoom = RoomController.playerRoom.get(map.get(token).user.getId());
        List<Player> players = thisRoom.getPlayers();
        for (String key : keys) {
            if (!map.get(key).token.equals(token)) {
                //找到当前房间，搜索房间里的人是否存在与这个map里的token
                Integer thisId = map.get(key).user.getId();//当前这个人是否在房间
                for (Player p : players) {
                    if (p.getId().equals(thisId)) {
                        //在房间内
                        map.get(key).session.getAsyncRemote().sendText(msg);
                    }
                }
            }
        }
    }

    /**
     * 发送信息给房间里的所有人
     * @param token
     * @param msg
     */
    public static void sendMsgAll(String token, String msg) {
        Set<String> keys = map.keySet();
        Room thisRoom = RoomController.playerRoom.get(map.get(token).user.getId());
        List<Player> players = thisRoom.getPlayers();
        for (String key : keys) {
            //找到当前房间，搜索房间里的人是否存在与这个map里的token
            Integer thisId = map.get(key).user.getId();//当前这个人是否在房间
            for (Player p : players) {
                if (p.getId().equals(thisId)) {
                    //在房间内
                    map.get(key).session.getAsyncRemote().sendText(msg);
                }
            }

        }
    }
}